home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / mikdll / mdllload.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-25  |  4.4 KB  |  256 lines

  1. /*
  2.     MikDLL - Done by MikMak / HaRDCoDE '95
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <dos.h>
  7. #include <string.h>
  8. #include "mdllload.h"
  9.  
  10. typedef unsigned short UWORD;
  11.  
  12. typedef struct{
  13.     UWORD signature;
  14.     UWORD partpag;
  15.     UWORD pagecnt;
  16.     UWORD relocnt;
  17.     UWORD hdrsize;
  18.     UWORD minmem;
  19.     UWORD maxmem;
  20.     UWORD reloss;
  21.     UWORD exesp;
  22.     UWORD chksum;
  23.     UWORD exeip;
  24.     UWORD relocs;
  25.     UWORD tabloff;
  26.     UWORD overlay;
  27. } EXEHEADER;
  28.  
  29. typedef struct EXPORTENTRY{
  30.     struct EXPORTENTRY *next;
  31.     char *name;
  32.     void *obj;
  33. } EXPORTENTRY;
  34.  
  35. static char *dll_error=NULL;
  36. static EXPORTENTRY *pool=NULL;
  37. static int removeexports=0;
  38.  
  39.  
  40. static EXPORTENTRY *findexportentry(char *name)
  41. {
  42.     EXPORTENTRY *e;
  43.  
  44.     e=pool;
  45.  
  46.     while(e!=NULL){
  47.         if(!strcmp(e->name,name)) break;
  48.         e=e->next;
  49.     }
  50.  
  51.     return e;
  52. }
  53.  
  54.  
  55. void huge MDLL_Export(char *name,void *obj)
  56. /*
  57.     MDLL_Export
  58.     ===========
  59.  
  60.     Adds an object (function or a datablock) to the exports-pool so a DLL
  61.     can use that object in the future.
  62.  
  63.     Input:
  64.  
  65.         char *name    :    The ASCIIZ name of the object to be exported, by
  66.                         which it will be registered in the exports-pool.
  67.  
  68.         void *obj    :    The address of the object to be exported.
  69.  
  70.  
  71.     Returns:
  72.         -
  73.  
  74.     Note:
  75.     This function never fails.. when the EXPORTENTRY can't be allocated,
  76.     it'll simply _not_ add the function to the exports-pool.
  77.  
  78.     Note 2:
  79.     When the static 'removeexports' is true, this function will go in reverse,
  80.     it will remove the objects referenced by 'name' from the exports-pool.
  81.     When a DLL has to be 'unlinked' I simply set removeexports to 1 , and call
  82.     the DLL entry point again; all objects previously exported will be removed
  83.     from the exports-pool.
  84. */
  85. {
  86.     EXPORTENTRY *e,*o;
  87.  
  88.     o=findexportentry(name);
  89.  
  90.     if(!removeexports){
  91.  
  92.         if(o!=NULL){
  93.             printf("\n'%s' exported twice.\n",name);
  94.             exit(0);
  95.         }
  96.  
  97.         printf("Exporting %s\n",name);
  98.  
  99.         e=malloc(sizeof(EXPORTENTRY));
  100.  
  101.         if(e==NULL) return;
  102.  
  103.         e->next=NULL;
  104.         e->name=name;
  105.         e->obj=obj;
  106.  
  107.         e->next=pool;
  108.         pool=e;
  109.     }
  110.     else{
  111.         printf("Removing %s from exports-pool\n",name);
  112.  
  113.         e=pool;
  114.         o->name=e->name;
  115.         o->obj=e->obj;
  116.         pool=e->next;
  117.         free(e);
  118.     }
  119. }
  120.  
  121.  
  122.  
  123. void * huge MDLL_Import(char *name)
  124. /*
  125.     MDLL_Import
  126.     ===========
  127.  
  128.     Finds the address of an object by reference of it's name. This routine
  129.     is used by a DLL to access external functions/data.
  130.  
  131.     Input:
  132.  
  133.         char *name    :    The ASCIIZ name of the object to be imported.
  134.  
  135.  
  136.     Returns:
  137.  
  138.         The address of the object.
  139.  
  140.     Note:
  141.     When the object can't be found, this function will report the failure and
  142.     exit the program.
  143. */
  144. {
  145.     EXPORTENTRY *e=findexportentry(name);
  146.  
  147.     if(e==NULL){
  148.         printf("\nCouldn't resolve external reference: '%s'\n",name);
  149.         exit(0);
  150.     }
  151.  
  152.     return e->obj;
  153. }
  154.  
  155.  
  156. void *MDLL_entry(MDLL *mp)
  157. {
  158.     long t;
  159.     char *s=mp->module;
  160.  
  161.     for(t=0;t<mp->modulesize;t++){
  162.         if(!memcmp(s,"MDLLTAG",7) && s[7]=='0'){
  163.             return(((TAG *)s)->func);
  164.         }
  165.         s++;
  166.     }
  167.     return NULL;
  168. }
  169.  
  170.  
  171. void MDLL_Unbind(MDLL *mp)
  172. {
  173.     removeexports=1;
  174.     mp->entryp(MDLL_Import,MDLL_Export);
  175.     removeexports=0;
  176.     free(mp->memblk);
  177. }
  178.  
  179.  
  180. int MDLL_Bind(MDLL *mp,char *name)
  181. {
  182.     FILE *fp;
  183.     EXEHEADER hdr;
  184.     union REGS regs;
  185.     struct SREGS sregs;
  186.  
  187.     struct{
  188.         int envseg;
  189.         int reloc;
  190.     } e;
  191.  
  192.     dll_error="No error";
  193.  
  194.     // open file & read exe header
  195.  
  196.     if((fp=fopen(name,"rb"))==NULL){
  197.         dll_error="Couldn't open MDLL executable";
  198.         return 0;
  199.     }
  200.     fread(&hdr,sizeof(EXEHEADER),1,fp);
  201.     fclose(fp);
  202.  
  203.     mp->modulesize=(512L*hdr.pagecnt)-(16L*hdr.hdrsize);
  204.  
  205.     // allocate memory for overlay
  206.  
  207.     if((mp->memblk=malloc(mp->modulesize+16))==NULL){
  208.         dll_error="MDLL memory block malloc failed, MDLL too big?";
  209.         return 0;
  210.     }
  211.  
  212.     // paragraph align module ptr
  213.  
  214.     mp->module=MK_FP(FP_SEG(mp->memblk)+1,0);
  215.  
  216.     // fill segment registers
  217.  
  218.     segread(&sregs);
  219.  
  220.     e.envseg=FP_SEG(mp->module);
  221.     e.reloc=FP_SEG(mp->module);
  222.  
  223.     regs.h.ah=0x4b;        // dos function 'EXEC'
  224.     regs.h.al=0x03;        // load overlay
  225.     sregs.ds=FP_SEG(name);
  226.     regs.x.dx=FP_OFF(name);
  227.  
  228.     sregs.es=FP_SEG(&e);
  229.     regs.x.bx=FP_OFF(&e);
  230.  
  231.     intdosx(®s,®s,&sregs);
  232.  
  233.     if(regs.x.cflag!=0){
  234.         free(mp->memblk);
  235.         dll_error="Dos func 0x4b failed";
  236.         return 0;
  237.     }
  238.  
  239.     mp->entryp=MDLL_entry(mp);
  240.  
  241.     if(mp->entryp==NULL){
  242.         free(mp->memblk);
  243.         dll_error="Couldn't find MDLL entrypoint";
  244.         return 0;
  245.     }
  246.  
  247.     mp->entryp(MDLL_Import,MDLL_Export);
  248.     return 1;
  249. }
  250.  
  251.  
  252. char *MDLL_Error(void)
  253. {
  254.     return dll_error;
  255. }
  256.